/*
 A custom facelets component that simulates block/cell input like the ones used on wire transfer or tax forms.
 Copyright (C) 2009 PragMindZ
 http://www.pragmindz.org
 mailto://info@pragmindz.org

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

var pm$bi = function()
{

    //private variables
    var input = new Array(12);
    var clientIds = new Array(12);

    var nonChar = false;
    var curChar;

    //private methods
    function handleNonChar(code, prev, next, elem, size, cellCB)
    {
        if (!nonChar && (cellCB != null))
        {
            var fcall = cellCB + "(curChar,input)";
            transCode = eval(fcall);
            elem.value = transCode;
            nonChar = true;
        }
        var pos = elem.getAttribute("pos");
        if (code == 8 || code == 37) //backspace or left-arrow respectively
        {
            if (code == 8) input[pos] = "";
            if (pos > 0)
            {
                var elt = document.getElementById(prev);
                elt.focus();
                elt.select();
            }
        }
        else if ((code < 32) || (code == 46)) //SHIFT and DELETE
        {
            return; //do-nothing
        }
        else
        {
            if (pos < (size - 1))
            {
                var elt = document.getElementById(next);
                elt.focus();
                elt.select();
            }
        }
    }

    function handleChar(code, next, elem, size, filter, callback, cellCB)
    {
        var transCode;
        var pos = elem.getAttribute("pos");
        input[pos] = String.fromCharCode(code);
        curChar = input[pos];
        var trimmed = input.join(""); //join without separator
        if (trimmed.length == size)
        {
            if (filter != null && callback != null)
            {
                if (trimmed.match(filter))
                {
                    eval(callback+"(true, trimmed)");
                }
                else
                {
                    eval(callback+"(false, trimmed)");
                }
            }
        }
    }

    //public methods
    return {
        handleKeys : function(e, elem)
        {
            //First, retrieve the element attributes
            var prev = elem.getAttribute("prev");
            var next = elem.getAttribute("next");
            var size = elem.getAttribute("size");
            var filter = elem.getAttribute("filter");
            var cellCB = elem.getAttribute("cellCallback");
            var callback = elem.getAttribute("callback");

            var evt = (e) ? e : window.event; //IE reports window.event
            if (evt.type == "keyup")
            {
                handleNonChar(evt.keyCode, prev, next, elem, size, cellCB);
            }
            else if (evt.type == "keydown")
            {
                var char = evt.keyCode;
                if (char < 16 || // non printables
                    (char > 16 && char < 32) || // avoid shift
                    (char > 32 && char < 41) || // navigation keys
                    char == 46)   // Delete Key (Add to these if you need)
                    nonChar = true;
                else
                    nonChar = false;
            }
            else // This is keypress
            {
                if (nonChar) return;
                var code = (evt.charCode) ? evt.charCode : evt.keyCode;
                if (code > 31 && code < 256) // safari and opera
                    handleChar(code, next, elem, size, filter, callback, cellCB);
            }
        },
        reset : function(elem)
        {
            var i=0;
            while (true)
            {
                var cell = document.getElementById(elem+"_"+i);
                if (cell == undefined)
                    break;
                cell.value = "";
                if (i == 0)
                    cell.focus();
                i++;
            }
            input=[];
        }
    };
}();


